#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <locale.h>
#include <stdint.h>
#include<string.h>

#define LINES 200
#define NAMELEN 1024
//定义一个字符串str：char str[1024] = {0}; 
//定义字符串数组，最多保存200个字符串，每个字符串最多1024个字节（算字符串尾标志'\0'）
char strlist[LINES][NAMELEN]={0};//定义了200个字符串，字符串的名称是：strlist[0], strlist[1],...,strlist[i]...strlist[199]
int front=0, rear=0;//头尾指针
void insert(char* dirname);//入队列
char* pop();//出队列
//入队列
void insert(char* dirname)
{
	strcpy(strlist[rear], dirname);
	//rear指向下一个位置 
	rear++;
	if(rear % LINES==0)
	{
		rear=0;
	}
}
char* pop()
{
	char* p = strlist[front];
	//front指向下一个位置 
	front++;
	if(front % LINES==0)
	{
		front=0;
	}
	return p;
}
int empty()
{
	//printf("front=%d, rear=%d\n", front, rear);
	//判空 
	if(front == rear)
	{
		return 1;
	}
	return 0;
}
void display()
{
	int i = front;
	while(i != rear)
	{
		printf("strlist[%d]=%s\n", i, strlist[i]);
		i++;
		if(i % LINES==0)
		{
			i=0;
		}
	}

}

int cmpstr(char* str1, char *str2)
{
	int len1 = strlen(str1);	
	int len2 = strlen(str2);
	if(len1 <= len2)
	{
		return -1;
	}
	if(strcmp(str1+(len1-len2), str2)==0)//假设str1:20个字节，str2:15个字节 ，比较str1的后15个字节与str2是否相同 
	{
		return 0;
	}
	return -1;
}

void finddir(char* fullpathdirname, char* str)//"../../../../", ".txt" 
{ 
	//1. 定义3个变量 
	DIR	*dp;
	struct dirent	*dirp;
	struct stat statbuf;
	//2.打开目录 
	if ((dp = opendir(fullpathdirname)) == NULL)
	{
		printf("can't open %s", fullpathdirname);
		return;
	} 
	//3.处理目录下的一项，一项一项的处理 
	while ((dirp = readdir(dp)) != NULL)
	{
		//cut off . and .. dir.
		char* s1 = ".";
		char* s2 = "..";
		int ret1,ret2;
		ret1 = strcmp(dirp->d_name, s1);
		ret2 = strcmp(dirp->d_name, s2);
		if (ret1==0 || ret2==0)
		{
			continue;
		}
		if(dirp->d_name[0]=='.')
		{
			continue;
		}

		//get full path
		char fullpath[1024]={0};
		strcpy(fullpath,fullpathdirname);//"../../../../" 或"../../../../aaa.mp3" 
		int len = strlen(fullpath);
        //printf("len=%d\n", len);
		if(fullpath[len-1]!='/')
		{
			fullpath[len]='/';
			len++;
			fullpath[len]=0;
		}
		strcat(fullpath, dirp->d_name);

		//get item state
	    	//printf("fullpath=%s, %s\n", fullpath, dirp->d_name);
		//if(stat(dirp->d_name, &statbuf)==-1)
		if(stat(fullpath, &statbuf)==-1)
		{
			printf("0000000000000000000,fullpath=%s\n", fullpath);
			continue;
		}
		else//get state success.
		{

			if(S_ISDIR(statbuf.st_mode))//dir
			{
				//printf("1111111111111%s\n", dirp->d_name);

				strcat(fullpath, "/");
				insert(fullpath);//入队列 
			}
			else//file
			{
				if(cmpstr(dirp->d_name, str)!=0)
				{
					//do nothing
				}
				else//如果是".txt"文件 
				{
					printf("%s\n", fullpath);//strcat(fullpath, dirp->d_name);
//					printf("%s\n", dirp->d_name);
				}
			}
		}

	}//end while 
	closedir(dp);
	if(!empty())
	{
		//display();
		char *dirpath=pop();
		finddir(dirpath, str);
	}
	//printf("one level over!\n");
}

//test code 
int main(int argc, char *argv[])
{
	if (argc != 2)
	{
		printf("usage: find directory_name");
		exit(-1);
	}
	finddir(argv[1], ".cc");
	printf("over\n");
	exit(0);
}
/*
int
main(int argc, char *argv[])
{

	DIR	*dp;
	struct dirent	*dirp;
	struct stat statbuf;
	struct passwd *pwd;
	struct group *grp;
	struct tm *tm;
	char datestring[256];

	if (argc != 2)
		printf("usage: ls directory_name");

	if ((dp = opendir(argv[1])) == NULL)
		printf("can't open %s", argv[1]);
	while ((dirp = readdir(dp)) != NULL)
	{
		printf("%s\n", dirp->d_name);

		//get enty's information
		if(stat(dirp->d_name, &statbuf)==-1)
		{
			printf("0000000000000000000\n");
			continue;
		}
		printf("111111111111111111\n");
		//print out type, permission,
		//printf("%10.10s", sperm(statbuf.st_mode));
		printf("%4d", statbuf.st_nlink);

		if((pwd=getpwuid(statbuf.st_uid))!=NULL)
		    printf("%-8.8s", pwd->pw_name);
		else
		    printf("%-8d", statbuf.st_uid);

//get register info
//printf("my name=[%s]\n", pwd->pw_name);
//printf("my passwd = [%s]\n", pwd->pw_passwd );
//printf("my uid= [%d]\n", pwd->pw_uid);
//printf("my gid = [%d]\n", pwd->pw_gid);
//printf("my gecos= [%s]\n", pwd->pw_gecos);
//printf("my dir= [%s]\n", pwd->pw_dir);
//printf("my shell= [%s]\n", pwd->pw_shell);

		if((grp=getgrgid(statbuf.st_gid))!=NULL)
		    printf("%-8.8s", grp->gr_name);
		else
		    printf("%-8d", statbuf.st_gid);

		printf("%9jd", (intmax_t)statbuf.st_size);

		tm=localtime(&statbuf.st_mtime);

		//get localized date string
		//strftime(datestring, sizeof(datestring), nl_langinfo(D_T_FMT), tm);
		//printf(" %s %s\n", datestring, dirp->d_name);
		printf(" %s\n", dirp->d_name);

	}

	closedir(dp);
	exit(0);
}
*/

/*
user@user-virtual-machine:~/mywork/PhaseOne/systemprogramming/002/finddir$ ./finddir ../../../../
../../../../datastruct/aaaaaaa/bbb.txt
../../../../PhaseOne/systemprogramming/001/1.txt
../../../../PhaseOne/systemprogramming/002/a.txt
../../../../PhaseOne/systemprogramming/002/mytestfile.txt
../../../../PhaseOne/linuxbase/shell/aaa.txt
../../../../PhaseOne/systemprogramming/001/filecopy/a.txt
../../../../PhaseOne/systemprogramming/001/filecopy/b.txt
../../../../PhaseOne/systemprogramming/001/remove/a.txt
../../../../PhaseOne/linuxbase/makefile/hello-02-02/readme.txt
../../../../PhaseOne/linuxbase/makefile/hello-01/readme.txt
../../../../PhaseOne/linuxbase/makefile/hello-03-02/readme.txt
../../../../PhaseOne/linuxbase/makefile/hello-02/readme.txt
../../../../PhaseOne/linuxbase/makefile/hello-03/readme.txt
../../../../PhaseOne/linuxbase/makefile/hello-02-03/readme.txt
../../../../PhaseOne/systemprogramming/002/fileio/ParentAndChildFileDiscription/thefile.txt
../../../../PhaseOne/systemprogramming/002/fileio/hello/mytestfile.txt
../../../../PhaseOne/systemprogramming/002/fileio/create/a.txt
../../../../PhaseOne/systemprogramming/002/fileio/chmod/a.txt
../../../../PhaseOne/systemprogramming/002/fileio/read/a.txt
../../../../PhaseOne/linuxbase/gdb/gdb/003/readme.txt
../../../../PhaseOne/linuxbase/gdb/gdb/001/readme.txt
../../../../PhaseOne/linuxbase/gdb/gdb/002/readme.txt
../../../../datastruct/aaaaaaa/bbbbbb/ccccc/ddddddd/eeeeeee/fffff/ggggg/hhhh/ppppp.txt
over
user@user-virtual-machine:~/mywork/PhaseOne/systemprogramming/002/finddir$
*/
